﻿using DataProcess.Interface;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

namespace DataDrive.Access
{
    public class DataDrive : IDataDrive
    {
        private OleDbConnection Conn;

        private Config Config;

        public event StartedHandler Started;
        public event StopedHandler Stoped;
        public event DataRecivedHandler DataRecived;
        public event ErrorNoticedHandler ErrorNoticed;
        public event WarnNoticedHandler WarnNoticed;
        public event InfoNoticedHandler InfoNoticed;
        public string Name
        {
            get
            {
                return $"文件路径({$"{Path.Combine(Config.FolderPath, Config.FileName)}"})";
            }
        }
        public string SourceName { get; set; }


        public bool Running
        {
            get
            {
                if (_queryTimer == null) return false;
                return _queryTimer.Enabled;
            }
        }

        System.Timers.Timer _queryTimer;

        public DataDrive(Config config)
        {
            Config = config;
            _queryTimer = new System.Timers.Timer
            {
                Interval = Config.Interval == 0 ? 300000 : Config.Interval * 1000
            };
            _queryTimer.Elapsed -= new System.Timers.ElapsedEventHandler(DataHandle);
            _queryTimer.Elapsed += new System.Timers.ElapsedEventHandler(DataHandle);
        }

        public void Start()
        {
            if (Config == null) return;

            if (!Config.Valided())
            {
                WarnNoticed?.Invoke($"数据驱动配置不全,无法启用驱动.详情如下:{Config.Message}");
                return;
            }
            string msg = string.Empty;
            try
            {
                string connStr = string.Empty;
                // 连接字符串
                if (string.IsNullOrEmpty(Config.PassWord))
                {
                    connStr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Config.FolderPath + "\\" + Config.FileName;
                }
                else
                {
                    connStr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Config.FolderPath + "\\" + Config.FileName + ";Jet OLEDB:Database Password=" + Config.PassWord;
                }
                // 初始化数据库连接，需要传递连接字符串
                Conn = new OleDbConnection(connStr);
                msg = $@"开始加载文件[{Config.FolderPath}\{Config.FileName}数据库驱动]";
                StartTimer();
                InfoNoticed?.Invoke(msg);
                Started?.Invoke();
            }
            catch (Exception ex)
            {
                Conn?.Close();
                Conn?.Dispose();
                ErrorNoticed?.Invoke(ex.Message);
            }
        }

        //定时任务
        private void StartTimer()
        {
            InfoNoticed?.Invoke($@"定时查询任务启动");
            _queryTimer.Enabled = true;
            _queryTimer.Start();
        }

        private void DataHandle(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                if (Conn == null)
                {
                    WarnNoticed?.Invoke($"数据驱动未开启");
                    return;
                }
                string sql;

                if (string.IsNullOrEmpty(Config.DateField))
                {
                    sql = $"{Config.Sql}";
                }
                else
                {
                    string whereSql = $" where {Config.DateField} > #{Config.Date}# ";

                    if (Regex.IsMatch(Config.Sql, "{[W|w][H|h][E|e][R|r][E|e]}"))
                    {
                        sql = Regex.Replace(Config.Sql, "{[W|w][H|h][E|e][R|r][E|e]}", whereSql);
                    }
                    else
                    {
                        sql = $"{Config.Sql} {whereSql}";
                    }
                }

                // 打开数据库连接hg
                Conn.Open();
                using (OleDbDataAdapter myCommand = new OleDbDataAdapter(sql, Conn))
                {
                    DataTable dt = new DataTable();
                    myCommand.Fill(dt);
                    if (dt.Rows.Count == 0) return;
                    string dateFileString = string.IsNullOrEmpty(Config.DateFieldAs) ? Config.DateField : Config.DateFieldAs;

                    if (dt.Columns.Contains(dateFileString))
                    {
                        if (DateTime.TryParse(dt.Rows[0][dateFileString].ToString(), out DateTime d))
                        {
                            Config.Date = d;
                        }
                    }

                    IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy/MM/dd HH:mm:ss" };
                    DataRecived?.Invoke(JsonConvert.SerializeObject(dt, dtConverter));
                }
            }
            catch (Exception ex)
            {
                Conn?.Close();
                Conn?.Dispose();
                ErrorNoticed?.Invoke(ex.Message);
            }
            finally
            {
                Conn?.Close();
            }
        }

        public void Stop()
        {
            _queryTimer?.Close();
            Conn?.Close();
            Stoped?.Invoke();
        }

        public void Dispose()
        {
            _queryTimer?.Close();
            _queryTimer?.Dispose();
            Conn?.Close();
            Conn?.Dispose();
        }
    }
    public class Config : IDataDriveConfig
    {

        [Display(Name = "文件夹路径")]
        public string FolderPath { get; set; }

        [Display(Name = "要读取的文件")]
        public string FileName { get; set; }

        [Display(Name = "数据库密码")]
        public string PassWord { get; set; }

        [Display(Name = "Sql语句")]
        public string Sql { get; set; }

        [Display(Name = "定时查询数据(秒)")]
        public int Interval { get; set; }

        [Display(Name = "查询时间点")]
        public DateTime Date { get; set; }

        [Display(Name = "查询时间点字段名称")]
        public string DateField { get; set; }

        [Display(Name = "查询时间点字段名称As")]
        public string DateFieldAs { get; set; }

        [Display(AutoGenerateField = false)]
        public string Message { get; set; }

        public bool Valided()
        {
            if (string.IsNullOrEmpty(FolderPath))
            {
                Message = "[文件夹路径]不能为空";
                return false;
            }

            if (string.IsNullOrEmpty(FileName))
            {
                Message = "[文件名称]不能为空";
                return false;
            }

            if (string.IsNullOrEmpty(Sql))
            {
                Message = "[Sql语句]不能为空";
                return false;
            }

            if (string.IsNullOrEmpty(Interval.ToString()))
            {
                Message = "[定时查询数据(秒)]不能为空";
                return false;
            }
            if (string.IsNullOrEmpty(Date.ToString()))
            {
                Message = "查询条件不能为空";
                return false;
            }
            if (string.IsNullOrEmpty(DateField.ToString()))
            {
                Message = "查询时间点字段名称不能为空";
                return false;
            }
            return true;
        }
    }
}
